//------------------------------------------------------------------------------
//!	@file	ProcGray.c
//!	@brief
//!		Process RGB type LUTs
//!
//!	@Description
//!		This file contains all of the RGB processing.
//!
//!
//!	Originally Developed: July, 1997 to October, 1999
//!
//!	$Id: ProcGray.c 158 2013-03-03 07:00:15Z ac.verbeck@gmail.com $
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//	Copyright and Disclaimer Notice
//
//	Copyright (c) 2013 A.C. Verbeck
//
//	This file is part of CreateLUT: A LUT creation library.
//
//	CreateLUT is free software: you can redistribute it and/or modify
//	it under the terms of the GNU General Public License as published by
//	the Free Software Foundation, either version 3 of the License, or
//	(at your option) any later version.
//
//	CreateLUT is distributed in the hope that it will be useful,
//	but WITHOUT ANY WARRANTY; without even the implied warranty of
//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//	GNU General Public License for more details.
//
//	You should have received a copy of the GNU General Public License
//	along with CreateLUT.  If not, see <http://www.gnu.org/licenses/>.
//
//------------------------------------------------------------------------------

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

#include <stdint.h>
#include <stdbool.h>

#include "ProcGray.h"
#include "dsp08.h"
#include "SysParam.h"

//
//	File local variables
//
static FILE	*OutFile;

//
//	Local functions
//
static void Gray_Load(char* InFile, double* g);
static void Gray_ProcessLut(double* InputRawEO);
static void Gray_WriteLut(uint8_t* tab);


//
//	Name:
//		Gray_Execute
//
//	Description:
//		Loads the raw color data into an array for further processing.
//		Does some error checking where possible.
//		Exits if error tests fail.
//
//	Parameters:
//		char*	InFile:		Input file
//		double*	gray		Gray data array
//
//	Returns:
//		(No direct return)
//		Indirect: The gray array is filled.
//
void Gray_Execute(void)
{
	double Gray[CURVE_SZ_08BIT];

	extern char InFileName[];
	extern char OutFileName[];

//
//	Load the raw EO curves
//
	Gray_Load(InFileName, Gray);

//
//	Open the output file & debug file
//
	OutFile = fopen(OutFileName,"wb");
	if (OutFile == NULL) {
		printf("File open error: %s\n",OutFileName);
		exit(1);
	}

//
//	Process the EO curves
//
	printf("Processing gray data:"); 			//	Process gray data
	Gray_ProcessLut(Gray);
	printf("Processing complete.\n"); 			//	Process complete

	fclose(OutFile);
}


//
//	Name:
//		Gray_Load
//
//	Description:
//		Loads the raw color data into an array for further processing.
//		Does some error checking where possible.
//		Exits if error tests fail.
//
//	Parameters:
//		char*	InFile:		Input file
//		double*	g:			Gray data array
//
//	Returns:
//		(No direct return)
//		Indirect: The g arrays are filled.
//
static void Gray_Load(char* InFile, double* g)
{
	FILE*	f;
	int32_t	i,fct;

	int32_t	ci;
	float	cg;
	float	pg;

	f = fopen(InFile,"r");
	if (f == NULL) {
		printf("File open error: %s\n",InFile);
		exit(1);
	}

	cg = 0.0;
	pg = 0.0;
	for (i=0; i<CURVE_SZ_08BIT; i++) {

		if ((fct = fscanf(f,"%d %f",&ci, &cg)) == EOF) {
			printf("EOF encountered!\n");
			exit(1);
		}
		if (fct != 2) {
			printf("Table formatting error.\n");
			exit(1);
		}

		if (ci > 255) {												//	Range test data
			printf("Table value out of range.\n");
			exit(1);
		}

		g[i] = cg;													//	Save gray

		//
		//	Gray testing
		//
		if (pg > cg) {
			printf("Warning: Gray data out of order!\n");
			printf("%d: Previous value: %6.3f Current Value: %6.3f\n",ci,pg,cg);
		}
		pg = cg;
	}
	fclose(f);
}



//
//	Name:
//		Gray_ProcessLut
//
//	Description:
//		This is the color driver.
//		Reads the color table and outputs all of the LUTs
//		for that color.
//
//	Parameters:
//		uint8_t*	InputFileName:	Input file name (color table)
//
//	Returns:
//		(None)
//
static void Gray_ProcessLut(double* InLut)
{
	double	GammaIdx,GammaInc;
	double	GainIdx,GainInc;
	uint8_t	OutLutTable[CURVE_SZ_08BIT];
	double	NormLutTable[CURVE_SZ_08BIT];
	double	FiltLut[CURVE_SZ_08BIT];

	int32_t	i,j;

	extern double	StartGamma;
	extern double	EndGamma;
	extern int32_t	LutGammaCt;

	extern double	StartGain;
	extern double	EndGain;
	extern int32_t	LutGainCt;

//
//	Process the file
//
	DSP08_Filter00(FiltLut, InLut);
	DSP08_Normalize(NormLutTable, FiltLut);

	GainInc  = (EndGain-StartGain)/(double)(LutGainCt-1);
	GammaInc = (EndGamma-StartGamma)/(double)(LutGammaCt-1);

	for (GainIdx=StartGain,i=0; i<LutGainCt; GainIdx+=GainInc,i++) {
		for (GammaIdx=StartGamma,j=0; j<LutGammaCt; GammaIdx+=GammaInc,j++) {
			memset(OutLutTable, 0, CURVE_SZ_08BIT);
			DSP08_BuildLUT(OutLutTable, NormLutTable, GainIdx, GammaIdx);
			Gray_WriteLut(OutLutTable);
		}
		printf(".");
	}
	printf("\n");
}


//
//	Name:
//		Gray_WriteLut
//
//	Description:
//		Writes a raw binary LUT table to a file.
//		This file will be converted to S-Records by the
//		SDS down program.
//
//	Parameters:
//		uint8_t*	tab:		Binary LUT table to be written.
//
//	Returns:
//		(No direct return)
//		Indirect: The tab[TABLE_SZ] array is written to the output file.
//
static void Gray_WriteLut(uint8_t* tab)
{
	fwrite(tab, 1, CURVE_SZ_08BIT, OutFile);
}


//
//	End: ProcGray.c
//
